package net.baribeau.pdfgen;

import org.apache.fop.apps.FOPException;
import org.apache.fop.apps.FOUserAgent;
import org.apache.fop.apps.Fop;
import org.apache.fop.apps.FopFactory;
import org.apache.fop.apps.MimeConstants;
import org.apache.fop.render.print.PrintRenderer;

import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXResult;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;
import java.awt.print.PrinterJob;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.OutputStream;

/**
 * This class performs the low-level XML rendering using the Apache FOP.  It does not contain business-dependent logics
 * and is intended for use as a generic utility class.
 */
public class XmlRenderer {

    private final FopFactory fopFactory = FopFactory.newInstance();

    
    public XmlRenderer(){
    	System.out.println("Renderer created.");
    } 
    /**
     * Transforms the given XML source and XSL file to PDF format and returns it as a stream, which can be piped to
     * other destination, e.g. a Web browser or a file.
     *
     * @param xmlSource    the XML
     * @param xslSource A Stylesheet ID
     * @param out          the PDF will be sent to this stream @throws FOPException         FOPException
     * @throws TransformerException if the transformation step fails
     * @throws FOPException         if the rendering step fails
     */
    public void createPdf(Source xmlSource, Source xslSource, OutputStream out)
            throws FOPException, TransformerException {

        // Construct FOP with desired output format (here, it is set to PDF format and written to a stream)
        final Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);

        fopTransform(fop, getFoSource(xmlSource, xslSource));
    }



    /**
     * @param xmlSource
     * @param xslSource
     * @return
     * @throws TransformerException
     */
    public static Source getFoSource(Source xmlSource, Source xslSource) throws TransformerException {
        final Transformer transformer = TransformerFactory.newInstance().newTransformer(xslSource);
        final ByteArrayOutputStream foStream = new ByteArrayOutputStream();

        final Result result = new StreamResult(foStream);
        transformer.transform(xmlSource, result);

        return new StreamSource(new ByteArrayInputStream(foStream.toByteArray()));
    }

    private static void fopTransform(Fop fop, Source foSource) throws FOPException, TransformerException {

        // Setup JAXP using identity transformer
        final TransformerFactory factory = TransformerFactory.newInstance();
        final Transformer transformer = factory.newTransformer(); // identity transformer

        final Result result = new SAXResult(fop.getDefaultHandler());
        transformer.transform(foSource, result);
    }
}